package com.kuaimacode.kframework.api.service.user;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.kuaimacode.kframework.api.service.AgentService;
import com.kuaimacode.kframework.api.service.MasterService;
import com.kuaimacode.kframework.api.service.SysMessageService;
import com.kuaimacode.kframework.api.service.UserService;
import com.kuaimacode.kframework.common.Constant;
import com.kuaimacode.kframework.mybatis.mapper.user.OrderDispatchMapper;
import com.kuaimacode.kframework.mybatis.models.agent.SysAgent;
import com.kuaimacode.kframework.mybatis.models.master.MasterWaitResp;
import com.kuaimacode.kframework.mybatis.models.user.*;
import com.kuaimacode.kframework.util.AlipayVoiceUtil;
import com.kuaimacode.kframework.util.CommonUtil;
import com.kuaimacode.kframework.util.ListUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 中元
 * @date 2019/04/08
 */
@Service
public class OrderDispatchService extends ServiceImpl<OrderDispatchMapper, OrderDispatch> {
	@Autowired
	private MasterService masterServices;
	@Autowired
	private UserService userServices;
	@Autowired
	private OrderService orderServices;
	@Autowired
	private SysMessageService sysMessageService;
	@Autowired
	private AgentService agentServices;

	@Value("${aliyuns.api.keyid}")
	private String accessKeyId;
	@Value("${aliyuns.api.secret}")
	private String accessKeySecret;
	@Value("${aliyuns.voice.callernumber}")
	private String callerNumber;
	@Value("${aliyuns.voice.ttscode}")
	private String ttsCode;
	/**
	 *  分页查找所有的数据
	 * @param pageNum 当前页码，从1开始
	 * @param pageSize  一页显示多少行
	 * @return
	 */
	public PageInfo<OrderDispatch> findAll(int pageNum, int pageSize) {
		PageHelper.startPage(pageNum, pageSize);
		List<OrderDispatch> datas = baseMapper.selectList(null);
		return new PageInfo<OrderDispatch>(datas);
	}

	/**
	 * 根据订单id查询单条记录
	 * @param orderId
	 * @return
	 */
	public OrderDispatch getByOrderId(Long orderId){
		QueryWrapper<OrderDispatch> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("order_id",orderId);
        queryWrapper.ne("status", 3);//不是已拒绝
		OrderDispatch orderDispatch = baseMapper.selectOne(queryWrapper);
		return orderDispatch;
	}


	/**
	 * 根据订单id查询单条记录
	 * @param orderId
	 * @return
	 */
	public OrderDispatch getByOrderId(Long orderId, Integer status){
		QueryWrapper<OrderDispatch> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("order_id",orderId);
		queryWrapper.eq("status", status);
		OrderDispatch orderDispatch = baseMapper.selectOne(queryWrapper);
		return orderDispatch;
	}

	/**
	 * 查找所有的数据未接单需要推送数据
	 * @return
	 */
	public List<OrderDispatch> findWaitPush() {
		QueryWrapper<OrderDispatch> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("status",1);
		queryWrapper.lt("push_count",1);
		List<OrderDispatch> datas = baseMapper.selectList(queryWrapper);
		return datas;
	}

	/**
	 * 查找所有的数据未接单需要语音通知的数据
	 * @return
	 */
	public List<OrderDispatch> findWaitCall() {
		QueryWrapper<OrderDispatch> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("status",1);
		queryWrapper.ge("push_count",1);
		queryWrapper.lt("call_count",2);
		List<OrderDispatch> datas = baseMapper.selectList(queryWrapper);
		return datas;
	}

	/**
	 * 查找所有的拒绝的订单
	 * @return
	 */
	public List<OrderDispatch> findRefuse(Integer orderId) {
		QueryWrapper<OrderDispatch> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("status",3);
		queryWrapper.ge("order_id",orderId);
		List<OrderDispatch> datas = baseMapper.selectList(queryWrapper);
		return datas;
	}

	/**
	 * 查找所有已经推送3次和电话2次的数据
	 * @return
	 */
	public List<OrderDispatch> findAllPushCall() {
		QueryWrapper<OrderDispatch> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("status",1);
		queryWrapper.ge("push_count",1);
		queryWrapper.ge("call_count",2);
		List<OrderDispatch> datas = baseMapper.selectList(queryWrapper);
		return datas;
	}

	/**
     * 自动派单
	 * @return
     */
	public boolean autoDispatch(){
		//查询所有跑腿的待接单订单
		List<OrderSimple> list = orderServices.queryAllOrdersNoPage(null, Constant.OrderStatusEnum.WAIT_ACCEPT.getCode(), null, null);
		if(list == null || list.size() == 0){
			return false;
		}
		for(int i=0;i<list.size();i++){
			OrderSimple temp = list.get(i);
			//查询派单类型
			SysAgent agent = agentServices.getById(temp.getAgentId());
			if(!"auto".equals(agent.getDispatchType()) || temp.getMasterId() != null){
				continue;
			}
			if(temp != null){
				//派单
				OrderDispatch orderDispatch = getByOrderId(temp.getOrderId());
				if(orderDispatch != null ){

                    continue;
				}else{
					orderDispatch = new OrderDispatch();
				}

				//查询所有在接单中的师傅
				List<MasterWaitResp> datas = masterServices.findWaitMaster(null, temp.getAgentId().toString(),null,null,"1","1","1", "1");
				if(datas == null || datas.size() == 0){
					//TODO 没有师傅接单，取消订单
				}else{
					//根据距离评分权重派单|每个师傅最多同时接5单|已拒绝不再派|技能是否匹配
					datas = datas.stream().filter(m->orderServices.checkDoingCount(m.getMasterId())).
							filter(m->orderServices.checkRefuse(temp.getOrderId().intValue(),m.getMasterId()))
							.filter(m->orderServices.checkMasterSkill(m,temp)).collect(Collectors.toList());
					//TODO 处理师傅的SkillTYpe

					datas.stream().forEach(m->{
						Double fromLatitude = Double.parseDouble(temp.getFromLatitude()==null?temp.getToLatitude():temp.getFromLatitude());
						Double fromLongitude = Double.parseDouble(temp.getFromLongitude()==null?temp.getToLongitude():temp.getFromLongitude());
						Double toLatitude = Double.parseDouble(m.getLatitude());
						Double toLongitude = Double.parseDouble(m.getLongitude());
						Double distance = CommonUtil.getDistance(fromLatitude,fromLongitude,toLatitude,toLongitude);
						distance = distance==null?0D:distance;
						m.setDistance(distance);
					});
					String[] fields = {"score","distance"};
					boolean[] aescs = {false, true};//降序，升序
					ListUtils.sort( datas, fields, aescs);

					if(datas.size()==0){
                        continue;
                    }
					MasterWaitResp master = datas.get(0);//选中的师傅

					if(master == null){
						continue;
					}
					//派单
					//OrderDispatch orderDispatch = getByOrderId(temp.getOrderId());
					//if(orderDispatch == null){
					//	orderDispatch = new OrderDispatch();
					//}
					orderDispatch.setCreateAt(new Date());
					orderDispatch.setDispatchBy(0L);
					orderDispatch.setMasterId(master.getMasterId());
					orderDispatch.setOrderId(temp.getOrderId());
					orderDispatch.setOrderNo(temp.getOrderNo());
					orderDispatch.setStatus(1);//状态 1-待接单 2-已接单 3-已拒绝
					orderDispatch.setAgentId(temp.getAgentId().toString());
					//orderDispatch.setPushCount(1);//1次推送
					orderDispatch.setDispatchType("auto");
					if(this.saveOrUpdate(orderDispatch)){
						Order order = orderServices.getById(temp.getOrderId());
						if(order != null){
							order.setDispatchMaster(master.getMasterId());//派单
							order.setUpdateAt(new Date());
							orderServices.updateById(order);
						}
					}
				}
			}

		}
		return true;
	}

	/**
	 * 派单订单发送通知
	 * @return
	 */
	public int dispatchPush(){
		int count = 0;
		List<OrderDispatch> list = this.findWaitPush();
		for(int i=0;i<list.size();i++){
			OrderDispatch orderDispatch = list.get(i);
			if(orderDispatch == null){
				continue;
			}
			//通知推送师傅
			Integer pushCount = orderDispatch.getPushCount();
			if(orderDispatch.getMasterId() != null && pushCount < 1 && orderDispatch.getStatus() == 1) {
				count++;
				//sysMessageService.saveMessage("闪到服务新订单", "系统向您派送了新的订单,订单号[" + orderDispatch.getOrderNo() + "]，请及时处理。", true, orderDispatch.getMasterId());
                OrderMore om = orderServices.queryOrderById(orderDispatch.getOrderId());
                Map<String,Object> map = new HashMap<>();
                if(om != null){
                	//person-管理员派单 auto-自动派单
                	if("auto".equals(orderDispatch.getDispatchType())){
						map.put("type", 1);//1-自动派单 2-取消 3-人工派单 4-新订单
					}else{
						map.put("type", 3);//1-自动派单 2-取消 3-人工派单 4-新订单
					}
                    map.put("orderId", om.getOrderId());
                    map.put("orderNo", om.getOrderNo());
                    map.put("orderType", om.getOrderType());
                    map.put("orderTypeName", om.getOrderTypeName());
                    map.put("amount", om.getAmount());
                    map.put("orderChildType", om.getOrderChildType());
                    map.put("orderChildTypeName", om.getOrderChildTypeName());
                    map.put("fromAddress", om.getFromAddress());
                    map.put("toAddress", om.getToAddress());
                    //新增
					map.put("hasPartner", om.getHasPartner());
					map.put("hasInstant", om.getHasInstant());
					map.put("hasInstantDesc", om.getHasInstantDesc());
					map.put("categoryName", om.getCategoryName());
					map.put("weight", om.getWeight());
					map.put("remark", om.getRemark());
					map.put("fromLatitude", om.getFromLatitude());
					map.put("fromLongitude", om.getFromLongitude());
					map.put("toLatitude", om.getToLatitude());
					map.put("toLongitude", om.getToLongitude());
					map.put("insurance", om.getInsurance());
					map.put("insuranceFee", om.getInsuranceFee());
					map.put("collectionAmount", om.getCollectionAmount());
					map.put("goodsAmount", om.getGoodsAmount());
					//计算师傅预计收入
					Map<String, BigDecimal> incomeMap = orderServices.getIncome(om.getOrderNo());
					if(incomeMap!=null){
						map.put("expectedIncome", incomeMap.get("master"));
					}else{
						map.put("expectedIncome", "0.00");
					}
                }
				sysMessageService.saveMessage("阿四服务新订单", "系统向您派送了新的订单，请及时处理。", true, orderDispatch.getMasterId(), map);
               	try{
					//缓存推送弹窗订单id
					User user = userServices.getById(orderDispatch.getMasterId());
					String ids = user.getPopupPaidan();
					if(ids == null){
						ids = om.getOrderId().toString();
					}else{
						ids = ids + ","+om.getOrderId().toString();
					}
					user.setPopupPaidan(ids);
					userServices.updateById(user);
				}catch (Exception e){
               		e.printStackTrace();
				}
				orderDispatch.setPushCount(pushCount>=1?1:pushCount+1);//修改推送数量
				orderDispatch.setUpdateAt(new Date());
				this.updateOrderDispatch(orderDispatch);
			}
		}
		return count;
	}



	/**
	 * 派单订单发送电话语音通知
	 * @return
	 */
	public int dispatchCall(){
		int count = 0;
		List<OrderDispatch> list = this.findWaitCall();
		for(int i=0;i<list.size();i++){
			OrderDispatch orderDispatch = list.get(i);
			if(orderDispatch == null){
				continue;
			}
			Integer cllCount = orderDispatch.getCallCount();
			if(cllCount == null){
				cllCount = 0;
			}
			//通知推送师傅
			if(orderDispatch.getMasterId() != null && cllCount < 2) {
				long time = (new Date().getTime() - orderDispatch.getUpdateAt().getTime())/1000;
				if(time<90){
					continue;
				}
				count++;
				//UserMaster um = masterServices.findByUserId(orderDispatch.getMasterId());
				User user = userServices.getById(orderDispatch.getMasterId());
				if(user != null){
					//语音通知
					AlipayVoiceUtil.singleCallByTts(accessKeyId,accessKeySecret,callerNumber,user.getPhone(),ttsCode, orderDispatch.getId().toString());
				}
				orderDispatch.setCallCount(cllCount>=2?2:cllCount+1);//修改推送数量
				orderDispatch.setUpdateAt(new Date());
				this.updateOrderDispatch(orderDispatch);
			}/*else{
				//重新派单 TODO
				orderDispatch.setStatus(3);//状态 1-待接单 2-已接单 3-已拒绝
				this.saveOrUpdate(orderDispatch);
			}*/
		}
		return count;
	}

	@Transactional
	public boolean updateOrderDispatch(OrderDispatch orderDispatch){
		return baseMapper.updateById(orderDispatch)>0;
	}


	/**
	 * 订单池新订单发送通知
	 * 新订单这块推送需要改一下，新订单推送以订单池是否有未接单为准，不再以下新订单推送，每间隔一次查询一下订单池的订单，如果有新订单就推送，没有就不推送，
	 * 有新订单，就是您有新的订单语音（新订单和指派订单时不关联的，按调整后的业务是只要查询到订单池有新订单就推送） 指派订单就是平台指派订单了语音，取消订单就是订单取消语音
	 * @return
	 */
	public int newOrderPush(Order order){
		//新下单不再推送
		int count = 0;
		if(order == null){
			return count;
		}
		if(order.getMasterId() != null && order.getType() != Constant.OrderTypeEnum.PAO_TUI.getCode()){
			//其他服务指定师傅
			OrderDispatch orderDispatch = getByOrderId(order.getId());
			if(orderDispatch == null){
				orderDispatch = new OrderDispatch();
			}
			//派单
			orderDispatch.setCreateAt(new Date());
			orderDispatch.setDispatchBy(0L);
			orderDispatch.setMasterId(order.getMasterId());
			orderDispatch.setOrderId(order.getId());
			orderDispatch.setOrderNo(order.getOrderNo());
			orderDispatch.setStatus(1);//状态 1-待接单 2-已接单 3-已拒绝
			orderDispatch.setAgentId(order.getAgentId());
            orderDispatch.setHasSet(1);//是指定师傅
			//orderDispatch.setPushCount(1);//1次推送
			orderDispatch.setDispatchType("auto");
			if(this.saveOrUpdate(orderDispatch)){
				if(order != null){
					order.setDispatchMaster(order.getMasterId());//派单
					order.setUpdateAt(new Date());
					orderServices.updateById(order);
				}
			}
			count++;
		}
		return count;
/*
		//查询派单类型
		SysAgent agent = agentServices.getById(order.getAgentId());
		if(!"person".equals(agent.getDispatchType())){
			return count;
		}
		//查询所有在接单中的师傅
		List<MasterWaitResp> datas = masterServices.findWaitMaster(null, order.getAgentId(),null,null,"1","1","1", "1");
		if(datas == null || datas.size() == 0){
			//TODO 没有师傅接单，取消订单
		}else {
			for(MasterWaitResp master:datas){
				//通知推送师傅
				if(master != null) {
					count++;
					OrderMore om = orderServices.queryOrderById(order.getId());
					Map<String,Object> map = new HashMap<>();
					if(om != null){
						map.put("type", 4);//1-自动派单 2-取消 3-人工派单 4-新订单
 						map.put("orderId", om.getOrderId());
						map.put("orderNo", om.getOrderNo());
						map.put("orderType", om.getOrderType());
						map.put("orderTypeName", om.getOrderTypeName());
						map.put("amount", om.getAmount());
						map.put("orderChildType", om.getOrderChildType());
						map.put("orderChildTypeName", om.getOrderChildTypeName());
						map.put("fromAddress", om.getFromAddress());
						map.put("toAddress", om.getToAddress());
					}
					sysMessageService.saveMessage("闪到服务新订单", "系统有新的订单，请及时处理。", true, master.getMasterId(),map);
				}
			}
		}
		return count;*/
	}
}

